package com.study.sfd.medicine.annotation;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UnderlineToCamelArgumentResolver extends AbstractCustomizeResolver {
  /**
   * 匹配_加任意一个字符
   */
  private static final Pattern UNDER_LINE_PATTERN = Pattern.compile("_(\\w)");

  @Override
  public boolean supportsParameter(MethodParameter methodParameter) {
    return methodParameter.hasParameterAnnotation(ParameterConvert.class);
  }

  @Override
  public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
    Object org = handleParameterNames(methodParameter, nativeWebRequest);
    valid(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory, org);
    return org;
  }

  /**
   * 处理参数
   *
   * @param parameter
   * @param webRequest
   * @return
   */
  private Object handleParameterNames(MethodParameter parameter, NativeWebRequest webRequest) {
    Object obj = BeanUtils.instantiate(parameter.getParameterType());
    BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
    Iterator<String> paramNames = webRequest.getParameterNames();
    while (paramNames.hasNext()) {
      String paramName = paramNames.next();
      Object o = webRequest.getParameter(paramName);
      System.out.println(paramName + "=" + o);
      wrapper.setPropertyValue(underLineToCamel(paramName), o);
    }
    return obj;
  }

  /**
   * 下换线转驼峰
   *
   * @param source
   * @return
   */
  private String underLineToCamel(String source) {
    Matcher matcher = UNDER_LINE_PATTERN.matcher(source);
    StringBuffer result = new StringBuffer();
    while (matcher.find()) {
      matcher.appendReplacement(result, matcher.group(1).toUpperCase());
    }
    matcher.appendTail(result);
    return result.toString();
  }
}